﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetworkAssetManager.Entity;
using System.Management;
using log4net; 
namespace NetworkAssetManager.WMI
{
    class Memory
    {
        private static readonly ILog _logger = LogManager.GetLogger(typeof(Memory));

        public enum FormFactorValues
        {
            Unknown = 0,
            Other = 1,
            SIP = 2,
            DIP = 3,
            ZIP = 4,
            SOJ = 5,
            Proprietary = 6,
            SIMM = 7,
            DIMM = 8,
            TSOP = 9,
            PGA = 10,
            RIMM = 11,
            SODIMM = 12,
            SRIMM = 13,
            SMD = 14,
            SSMP = 15,
            QFP = 16,
            TQFP = 17,
            SOIC = 18,
            LCC = 19,
            PLCC = 20,
            BGA = 21,
            FPBGA = 22,
            LGA = 23,
            NULL = 24,
        }

        public enum MemoryTypeValues
        {
            Unknown = 0,
            Other = 1,
            DRAM = 2,
            Synchronous_DRAM = 3,
            Cache_DRAM = 4,
            EDO = 5,
            EDRAM = 6,
            VRAM = 7,
            SRAM = 8,
            RAM = 9,
            ROM = 10,
            Flash = 11,
            EEPROM = 12,
            FEPROM = 13,
            EPROM = 14,
            CDRAM = 15,
            Val_3DRAM = 16,
            SDRAM = 17,
            SGRAM = 18,
            RDRAM = 19,
            DDR = 20,
            NULL = 21,
        }

        private static EntMemory FillDetails(ManagementBaseObject obj)
        {
            EntMemory objEntMemory = new EntMemory();

            try
            {
                objEntMemory.BankLabel = WMIUtil.ToString(obj["BankLabel"]);
            }
            catch (Exception)
            {
                objEntMemory.BankLabel = "";
            }

            try
            {
                objEntMemory.Capacity = WMIUtil.ConvertSizetoString((UInt64)obj["Capacity"], true, NetworkAssetManager.General.Units.Auto);
            }
            catch (Exception)
            {
                objEntMemory.Capacity = "";
            }

            try
            {
                objEntMemory.DeviceLocator = WMIUtil.ToString(obj["DeviceLocator"]);
            }
            catch (Exception)
            {
                objEntMemory.DeviceLocator = "";
            }

            try
            {
                FormFactorValues formFactor = (FormFactorValues)WMIUtil.ToInteger(obj["FormFactor"]);
                objEntMemory.FormFactor = formFactor.ToString();
            }
            catch (Exception)
            {
                objEntMemory.FormFactor = "";
            }

            try
            {
                objEntMemory.Manufacturer = WMIUtil.ToString(obj["Manufacturer"]);
            }
            catch (Exception)
            {
                objEntMemory.Manufacturer = "";
            }

            try
            {
                MemoryTypeValues memType = (MemoryTypeValues)WMIUtil.ToInteger(obj["MemoryType"]);
                objEntMemory.MemoryType = memType.ToString();
            }
            catch (Exception)
            {
                objEntMemory.MemoryType = "";
            }

            try
            {
                objEntMemory.Speed = WMIUtil.ToString(obj["Speed"]) + " ns";
            }
            catch (Exception)
            {
                objEntMemory.Speed = ""; 
            }

            return objEntMemory;
        }
        public static List<EntMemory> GetMemoryDetails(ManagementScope scope)
        {
            _logger.Info("Collecting memory details for machine " + scope.Path.Server);

            ObjectQuery query = null;
            ManagementObjectSearcher searcher = null;
            ManagementObjectCollection objects = null;
            List<EntMemory> lstMemory = new List<EntMemory>();

            try
            {
                query = new ObjectQuery("Select * from Win32_PhysicalMemory");
                searcher = new ManagementObjectSearcher(scope, query);
                objects = searcher.Get();
                lstMemory.Capacity = objects.Count;
                foreach (ManagementBaseObject obj in objects)
                {
                    lstMemory.Add(FillDetails(obj));
                    obj.Dispose();
                }
            }
            catch (System.Exception e)
            {
                _logger.Error("Exception is memory collection " + e.Message);
            }
            finally
            {
                searcher.Dispose();
            }
            return lstMemory;
        }

    }
}
